<?php


namespace App\HttpController\Api\System;


use App\Common\AuthService;
use App\Common\Debug;
use App\Common\Rabbitmq;
use App\Common\Redis;
use App\Cron\Queue\TestQueue;
use App\HttpController\Api\Base;
use App\Models\AuthModel;
use App\Models\AuthNodeModel;
use App\Models\MenuModel;
use App\Models\NodeModel;
use App\Models\TextModel;
use App\Models\UserModel;
use EasySwoole\Component\Timer;
use EasySwoole\EasySwoole\Config;
use EasySwoole\FastCache\Cache;
use EasySwoole\Http\Message\Status;
use EasySwoole\Jwt\Jwt;
use EasySwoole\Mysqli\QueryBuilder;
use EasySwoole\Queue\Job;
use EasySwoole\Validate\Validate;
use PhpAmqpLib\Message\AMQPMessage;


class User extends Base
{
    /**
     * @var UserModel|null
     */
    private $model = null;

    public function __construct()
    {
        parent::__construct();
        $this->model = UserModel::getInstance();
    }

    /**
     * @throws \EasySwoole\Mysqli\Exception\Exception
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     */
    public function login()
    {
        $data = $this->requestData;
        $userModel = new UserModel();
        $result = $userModel->userFindOne($data['username']);
        if (empty($result)) {
            $this->writeJson(new \stdClass(), '用户不存在', Status::CODE_BAD_REQUEST);
            return false;
        }
        if ($result['password'] != md5($data['password'])) {
            $this->writeJson(new \stdClass(), '密码错误', Status::CODE_BAD_REQUEST);
            return false;
        }
        if ($result['status'] != 1) {
            $this->writeJson(new \stdClass(), '账号被禁用,请联系管理员', Status::CODE_BAD_REQUEST);
            return false;
        }
        unset($result['password']);
        $jwtConf = Config::getInstance()->getConf('JWT');
        //设置加密方式 支持AES 与 HMACSHA256 设置密钥默认为EasySwoole
        $jwtObj = Jwt::getInstance()->setSecretKey($jwtConf['key'])->publish();
        //设置参数
        $jwtObj->setIss($jwtConf['iss']); // 发行人
        $jwtObj->setNbf(time()); //设置在什么时间之前不可用
        $jwtObj->setExp(time() + $jwtConf['exp']); //设置过期时间时间
        $jwtObj->setData([
            'user_id' => $result['id'],
            'username' => $result['username'],
        ]); //设置带有的参数
        $token = $jwtObj->__toString();//生成token

        $this->writeJson([
            'token' => $token,
            'menu' => $this->getMenu($result['id']), //菜单栏目
            'auth' => $this->getAuth($result['id'], json_decode($result['auth_id'], true)),
            'user_info' => $result
        ]);
    }

    public function countOff()
    {
        $articleid = [171030,171029];
        $a = TextModel::create()->where(['date' => '2019-12-14'])->field('news_json,officialid')->select();
        foreach ($a as $v) {
            $b = json_decode($v['news_json'], true);
            if (in_array($b[1]['articleid'], $articleid)) {
                file_put_contents($b[1]['articleid'] . '.txt', $v['officialid'].PHP_EOL, FILE_APPEND);
            }
        }


    }

    /**
     * @param $userId int 用户id
     * @return array
     * @throws \EasySwoole\Mysqli\Exception\Exception
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     *
     * 获取菜单栏
     */
    private function getMenu(int $userId)
    {
        $model = MenuModel::getInstance();
        $nav = $model->getMenuList();
        foreach ($nav as $vo) {
            $i = 0;
            //查询儿子菜单地址
            $first_menu = $model->getChildrenMenus($vo['id']);
            foreach ($first_menu as $vo_1) {
                $authService = AuthService::getInstance();
                // 验证是否有权限
                if ($authService->checkNode($vo_1['href'], $userId)) {
                    if (!empty($vo_1['href']) && $vo_1['href'] != "#") {
                        $vo_1['href'] = '/' . $vo_1['href'];
                    }
                    $vo_1['spread'] = (bool)$vo_1['spread'];
                    $menu_list['easy_Liu' . $vo['id']][$i] = $vo_1;
                    // 查询儿子栏目
                    $second_menu = $model->getChildrenMenus($vo_1['id']);
                    foreach ($second_menu as $vo_2) {
                        if ($authService->checkNode($vo_2['href'], $userId)) {
                            if (!empty($vo_2['href']) && $vo_2['href'] != "#") {
                                $vo_2['href'] = '/' . $vo_2['href'];
                            }
                            $vo_2['spread'] = (bool)$vo_2['spread'];
                            $menu_list['easy_Liu' . $vo['id']][$i]['children'][] = $vo_2;
                        }
                    }
                    //去除空菜单
                    if (!isset($menu_list['easy_Liu' . $vo['id']][$i]['children'])) {
                        if ($menu_list['easy_Liu' . $vo['id']][$i]['href'] == '#' || $menu_list['easy_Liu' . $vo['id']][$i]['href'] == '') {
                            unset($menu_list['easy_Liu' . $vo['id']][$i]);
                        } else {
                            $i++;
                        }
                    } else {
                        $i++;
                    }
                }
            }
        }
//        菜单栏目栏目合并
        foreach ($nav as $k => &$v) {
            if (isset($menu_list['easy_Liu' . $v['id']])) {
                $v['sub'] = $menu_list['easy_Liu' . $v['id']];
            } else {
                unset($nav[$k]);
            }
        }
        return array_values($nav);
    }

    /**
     * @param int $userId
     * @param array $auth_id
     * @return array
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     * 获取用户所有权限
     */
    private function getAuth(int $userId, array $auth_id)
    {
        //判断当前登录是否为超级管理员
        if ($userId === 1) {
            $auth = NodeModel::create()->where(['type' => 3])->field('node,route_url,id')->select();
        } else {
            $auth = AuthModel::create()->alias('a')->where(function (QueryBuilder $query) use ($auth_id) {
                $query
                    ->join('system_auth_node as n', 'a.id=n.auth', 'LEFT')
                    ->join('system_node as n2', 'n.node=n2.id', 'LEFT')
                    ->where('a.id', $auth_id, 'in')
                    ->where('n2.type', 3, '=')
                    ->where('a.status', 1, '=');

            })->field('n2.node,n2.route_url,n2.id')->select();
        }
        return $auth;
    }

    /**
     * 用户列表
     */
    public function list()
    {
        $res = UserModel::getInstance()->list($this->page, $this->limit, $this->search);
        $this->writeJson($res);
    }

    /**
     * @return bool
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     * 删除用户
     */
    public function del()
    {
        $userId = $this->request()->getParsedBody('id');
        $res = UserModel::create()->where(['id' => $userId])->update(['is_deleted' => 1]);
        if ($res) {
            $this->writeJson($this->success('删除成功'));
        } else {
            $this->writeJson($this->error('删除失败'));
        }
        return false;
    }

    /**
     * @return bool
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     * 用户状态
     */
    public function status()
    {
        $userData = $this->request()->getParsedBody();
        $res = UserModel::create()->where(['id' => $userData['id']])->update(['status' => $userData['status']]);
        $msg = $userData['status'] ? '启用' : '禁用';
        if ($res) {
            $this->writeJson($this->success($msg . '成功'));
        } else {
            $this->writeJson($this->error($msg . '失败'));
        }
        return false;
    }

    /**
     * @return bool
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     * 修改密码
     */
    public function edit_password()
    {
        $res = UserModel::create()->where(['id' => $this->requestData['id']])->update(['password' => md5($this->requestData['password'])]);
        if ($res) {
            $this->writeJson($this->success('密码重置成功'));
        } else {
            $this->writeJson($this->error('密码重置失败'));
        }
        return false;
    }

    /**
     * @return bool
     * 添加用户
     */
    public function add()
    {
        if (!is_array(json_decode($this->requestData['auth_id'], true))) {
            $this->error('auth_id 权限角色组格式不正确');
            return false;
        }
        try {
            $userModel = UserModel::create([
                'auth_id' => trim($this->requestData['auth_id']),
                'username' => $this->requestData['username'],
                'password' => md5($this->requestData['password']),
                'remark' => $this->requestData['remark'],
                'head_img' => $this->requestData['head_img'],
                'qq' => $this->requestData['qq'],
                'mail' => $this->requestData['mail'],
                'phone' => $this->requestData['phone'],
            ]);
            $userModel->save();
            $this->writeJson($this->success('添加用户成功'));
        } catch (\Throwable $t) {
            $this->writeJson($this->error('添加用户异常'));
            $this->errorLog($t);
        }
        return false;
    }

    /**
     * @return bool
     * 编辑
     */
    public function edit()
    {
        if (!is_array(json_decode($this->requestData['auth_id'], true))) {
            $this->error('auth_id 权限角色组格式不正确');
            return false;
        }
        try {
            $update = [
                'auth_id' => trim($this->requestData['auth_id']),
                'remark' => $this->requestData['remark'],
                'head_img' => $this->requestData['head_img'],
                'qq' => $this->requestData['qq'],
                'mail' => $this->requestData['mail'],
                'phone' => $this->requestData['phone'],
            ];
            UserModel::getInstance()->update($update, ['id' => $this->requestData['id']]);
            $this->writeJson($this->success('编辑用户成功'));
        } catch (\Throwable $t) {
            $this->writeJson($this->error('编辑用户异常'));
            $this->errorLog($t);
        }
        return false;
    }

    //获取用户信息
    public function info()
    {
        $res = UserModel::getInstance()->where(['id' => $this->requestData['id']])->findOne();
        unset($res['password']);
        return $this->writeJson($res);
    }


    /**
     * @param string|null $action
     * @return Validate|null
     * 接口参数效验
     */
    protected function getValidateRule(?string $action): ?Validate
    {
        $validate = new Validate();
        switch ($action) {
            case 'login':
                $validate->addColumn('username', '用户名')->required();
                $validate->addColumn('password', '登录密码')->required();
                break;
            case 'status':
                $validate->addColumn('status', '用户状态')->required()->min(0)->max(1);
                break;
            case 'edit_password':
                $validate->addColumn('password', '新密码')->required()->lengthMax(32)->lengthMin(6);
                break;
            case 'add':
                $validate->addColumn('password', '密码')->lengthMin(32)->lengthMin(6)->required();
                break;
        }
        $actionAll = ['del', 'status', 'edit_password', 'edit', 'info'];
        if (in_array($action, $actionAll)) {
            $validate->addColumn('id', '用户id')->required()->min(2);
        }
        if ($action == 'add' || $action == 'edit') {
            $validate->addColumn('auth_id', '权限列表角色ID')->required();
            $validate->addColumn('username', '用户名')->required()->lengthMax(32)->lengthMin(4);
            $validate->addColumn('remark', '备注')->lengthMax(100);
            $validate->addColumn('head_img', '头像')->lengthMax(100);
            $validate->addColumn('qq', 'qq')->lengthMax(32);
            $validate->addColumn('mail', '邮箱')->lengthMax(32);
            $validate->addColumn('phone', '电话')->lengthMax(11);
        }
        return $validate;
    }

    //投递队列任务 示例
    private function pushQueue()
    {
        Timer::getInstance()->loop(2000, function () {
            $job = new Job();
            $job->setJobData(['time' => \time(), 'number' => 1]);
            TestQueue::getInstance()->producer()->push($job);
        });
    }

    // 延时队列消息投递
    private function FastCacheQueue()
    {
        Timer::getInstance()->loop(2000, function () {
            $job = new \EasySwoole\FastCache\Job();
            $job->setData(['name' => 'liuqiang', 'age' => 1, 'time' => time() + 5, 'msg' => '我是延时消息']); // 任意类型数据
            $job->setQueue("fast_cache_queue");
            $job->setDelay(5);
            $jobId = Cache::getInstance()->putJob($job);
            var_dump($jobId);
        });
    }

}
